/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.gui.client;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import nfse.gui.query.QuerySummary;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.widgets.MessageBox;

public class SearchResultsTab extends FlexTable {

    private HashMap checkedMyQueriesIDs = new HashMap(10);

    final FlexTable searchResultsTable = new FlexTable();

    final FlexTable searchResultsEntryTable = new FlexTable();

    NetFSEClient client = null;

    public SearchResultsTab(NetFSEClient client) {
        this.client = client;
        FlexTable myQueriesButtonTable = new FlexTable();

        Hyperlink myQueriesDeleteButton = new Hyperlink("Delete", "DeleteSearchResult");
        myQueriesDeleteButton.setText("Delete");
        myQueriesDeleteButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                Vector temp = new Vector();
                Iterator it = checkedMyQueriesIDs.keySet().iterator();
                while (it.hasNext()) {
                    String qid = (String) it.next();
                    temp.addElement(qid);
                }

                if (temp.size() == 0) {
                    MessageBox.alert("You must select at least one Search Result to delete.");
                    return;
                }

                String[] queryIDs = new String[temp.size()];
                for (int i = 0; i < queryIDs.length; i++) {
                    queryIDs[i] = (String) temp.elementAt(i);
                }
                deleteQueries(queryIDs);
            }
        });

        Hyperlink mergeButton = new Hyperlink("Merge", "MergeSearchResults");
        // mergeButton.setText("Merge");

        mergeButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                Vector temp = new Vector();
                Iterator it = checkedMyQueriesIDs.keySet().iterator();
                while (it.hasNext()) {
                    String qid = (String) it.next();
                    temp.addElement(qid);
                }

                String[] queryIDs = new String[temp.size()];
                for (int i = 0; i < queryIDs.length; i++) {
                    queryIDs[i] = (String) temp.elementAt(i);
                }
                mergeQueries(queryIDs);
            }
        });

        Hyperlink myQueriesRefreshButton = new Hyperlink("Refresh", "RefreshSearchResults");
        // mergeButton.setText("Merge");

        myQueriesRefreshButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                myQueries();
            }
        });

        Hyperlink makePermanentButton = new Hyperlink("Make Permanent", "MakePermanent");
        makePermanentButton.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                Vector temp = new Vector();
                Iterator it = checkedMyQueriesIDs.keySet().iterator();
                while (it.hasNext()) {
                    String qid = (String) it.next();
                    temp.addElement(qid);
                }

                String[] queryIDs = new String[temp.size()];
                for (int i = 0; i < queryIDs.length; i++) {
                    queryIDs[i] = (String) temp.elementAt(i);
                }
                makePermanent(queryIDs);
            }
        });

        myQueriesButtonTable.setWidget(0, 0, new Label("Actions: "));
        myQueriesButtonTable.setWidget(0, 1, myQueriesRefreshButton);
        myQueriesButtonTable.setWidget(0, 2, new Label("|"));
        myQueriesButtonTable.setWidget(0, 3, myQueriesDeleteButton);
        myQueriesButtonTable.setWidget(0, 4, new Label("|"));
        myQueriesButtonTable.setWidget(0, 5, mergeButton);
        myQueriesButtonTable.setWidget(0, 6, new Label("|"));
        myQueriesButtonTable.setWidget(0, 7, makePermanentButton);
        // myQueriesButtonTable.setWidget(0, 6, new Label("|"));
        // myQueriesButtonTable.setWidget(0, 7, timelineButton);

        // searchResultsTable.setHTML(0, 0, "<h2>Search Results</h2>");
        this.setWidget(0, 0, myQueriesButtonTable);
        this.setWidget(1, 0, searchResultsEntryTable);
    }

    private synchronized void deleteQueries(String[] queryIDs) {

        String msg = "";
        if (queryIDs.length == 1) {
            msg = "Are you sure you want to delete the Search Result for Search " + queryIDs[0] + "?";
        } else {
            msg = "The folowing Search Results will be deleted: ";
            for (int i = 0; i < queryIDs.length; i++) {
                msg += queryIDs[i];
                if (i != queryIDs.length - 1) {
                    msg += ", ";
                }
            }
            msg += ".\n Are you sure you want to delete these Search Results?";
        }
        final String[] tempQueryIDs = queryIDs;
        MessageBox.confirm("Confirm", msg, new MessageBox.ConfirmCallback() {
            public void execute(String btnID) {
                if (btnID.equals("yes")) {
                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                    AsyncCallback callback = new AsyncCallback() {
                        public void onFailure(Throwable caught) {
                            NetFSEClient.redirect("NetFSEClient.html");
                        }

                        public void onSuccess(Object result) {
                            Vector temp = new Vector();
                            Iterator it = checkedMyQueriesIDs.keySet().iterator();
                            while (it.hasNext()) {
                                String qid = (String) it.next();
                                temp.addElement(qid);
                            }
                            for (int i = 0; i < temp.size(); i++) {
                                checkedMyQueriesIDs.remove(temp.elementAt(i));
                            }
                            myQueries();
                        }
                    };

                    NetFSEService.multiDelete(tempQueryIDs, callback);
                }
            }
        });

    }

    private synchronized void deleteQuery(String queryID) {
        final String tempQueryID = queryID;
        MessageBox.confirm("Confirm", "Are you sure you want to delete Search Result " + queryID + "?",
                new MessageBox.ConfirmCallback() {
                    public void execute(String btnID) {
                        if (btnID.equals("yes")) {
                            QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

                            ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
                            endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                            AsyncCallback callback = new AsyncCallback() {
                                public void onFailure(Throwable caught) {
                                    NetFSEClient.redirect("NetFSEClient.html");
                                }

                                public void onSuccess(Object result) {
                                    myQueries();
                                }
                            };

                            nfseService.delete(tempQueryID, callback);
                        }
                    }
                });

    }

    private void makePermanent(String queryID) {
        final String tempQueryID = queryID;
        MessageBox.confirm("Confirm", "Are you sure you want to make Search Results for Search " + queryID
                + " permanent?", new MessageBox.ConfirmCallback() {
            public void execute(String btnID) {
                if (btnID.equals("yes")) {
                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                    AsyncCallback callback = new AsyncCallback() {
                        public void onFailure(Throwable caught) {
                            NetFSEClient.redirect("NetFSEClient.html");
                        }

                        public void onSuccess(Object result) {
                            myQueries();
                        }
                    };

                    NetFSEService.makePermanent(tempQueryID, callback);
                }
            }
        });

    }

    private void makePermanent(String[] queryIDs) {

        if (NetFSEClient.IS_TEST_DRIVE) {
            MessageBox.alert("Make Permanent is disabled for the Test Drive. Sorry!");
            return;
        }

        String msg = "";
        if (queryIDs.length == 1) {
            msg = "Are you sure you want to make Search Results for Search " + queryIDs[0] + " permanent?";
        } else {
            msg = "The folowing Search Results will be made permanent: ";
            for (int i = 0; i < queryIDs.length; i++) {
                msg += queryIDs[i];
                if (i != queryIDs.length - 1) {
                    msg += ", ";
                }
            }
            msg += ".\n Are you sure you want to make these Search Results permanent?";
        }
        final String[] tempQueryIDs = queryIDs;
        MessageBox.confirm("Confirm", msg, new MessageBox.ConfirmCallback() {
            public void execute(String btnID) {
                if (btnID.equals("yes")) {
                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                    AsyncCallback callback = new AsyncCallback() {
                        public void onFailure(Throwable caught) {
                            NetFSEClient.redirect("NetFSEClient.html");
                        }

                        public void onSuccess(Object result) {
                            myQueries();
                        }
                    };

                    NetFSEService.multiMakePermanent(tempQueryIDs, callback);
                }
            }
        });
    }

    private synchronized void mergeQueries(String[] queryIDs) {

        String msg = "";
        if (queryIDs.length == 1) {
            MessageBox.alert("You must select more than one Search Result to perform a merge.");
            return;
        } else {
            msg = "The folowing Search Results will be merged into Search " + queryIDs[0] + ": ";
            for (int i = 1; i < queryIDs.length; i++) {
                msg += queryIDs[i];
                if (i != queryIDs.length - 1) {
                    msg += ", ";
                }
            }
            msg += ".\n Are you sure you want to merge these Search Results?";
        }

        final String[] tempQueryIDs = queryIDs;
        MessageBox.confirm("Confirm", msg, new MessageBox.ConfirmCallback() {
            public void execute(String btnID) {
                if (btnID.equals("yes")) {
                    QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

                    ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
                    endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

                    AsyncCallback callback = new AsyncCallback() {
                        public void onFailure(Throwable caught) {
                            NetFSEClient.redirect("NetFSEClient.html");
                        }

                        public void onSuccess(Object result) {
                            MessageBox.alert((String) result);
                            myQueries();
                        }
                    };
                    NetFSEService.merge(tempQueryIDs, callback);
                    myQueries();
                }
            }
        });

    }

    public synchronized void myQueries() {
        QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirect("NetFSEClient.html");
            }

            public void onSuccess(Object result) {
                FlexTable.FlexCellFormatter formatter = searchResultsEntryTable.getFlexCellFormatter();
                searchResultsEntryTable.setStyleName("nfsetable");
                searchResultsEntryTable.addStyleName("nfsetbody");

                // myQueriesEntryTable.setStyleName("table.nfse");

                QuerySummary[] summaries = (QuerySummary[]) result;
                // myQueriesCheckBoxes = new CheckBox[summaries.length];
                if (summaries == null || summaries.length == 0) {
                    while (searchResultsEntryTable.getRowCount() > 0)
                        searchResultsEntryTable.removeRow(0);
                    searchResultsEntryTable.setHTML(0, 0, "No Search Results currently stored in the database.");
                    return;
                }

                if (searchResultsEntryTable.getRowCount() <= 1) {
                    int idx = -1;
                    // myQueriesEntryTable.setBorderWidth(1);

                    // myQueriesEntryTable.setHTML(0, ++idx, "");

                    searchResultsEntryTable.setHTML(0, ++idx, "");
                    searchResultsEntryTable.setHTML(0, ++idx, "<B>Search ID</b>");
                    formatter.addStyleName(0, idx, "tdleft");
                    formatter.setWordWrap(0, idx, false);
                    // myQueriesEntryTable.setHTML(0, ++idx,
                    // "<b>Actions</b>");
                    // formatter.setStyleName(0, idx, "tdleft");
                    // formatter.setWordWrap(0, idx, false);
                    // myQueriesEntryTable.setHTML(0, ++idx,
                    // "<b>Expires</b>");
                    // formatter.addStyleName(0, idx, "tdleft");
                    // formatter.setWordWrap(0, idx, false);
                    searchResultsEntryTable.setHTML(0, ++idx, "<b>Note</b>");
                    formatter.addStyleName(0, idx, "tdleft");
                    formatter.setWordWrap(0, idx, false);
                    searchResultsEntryTable.setHTML(0, ++idx, "<b>Expires</b>");
                    formatter.addStyleName(0, idx, "tdleft");
                    formatter.setWordWrap(0, idx, false);
                    searchResultsEntryTable.setHTML(0, ++idx, "<b>Status</b>");
                    formatter.addStyleName(0, idx, "tdleft");
                    formatter.setWordWrap(0, idx, false);

                    int[] types = client.getAllTypes();
                    for (int i = 0; i < types.length; i++) {
                        searchResultsEntryTable.setHTML(0, ++idx, "<b>" + client.getTypeName(types[i]) + "</b>");
                        formatter.addStyleName(0, idx, "tdleft");
                        formatter.setWordWrap(0, idx, false);
                    }

                    searchResultsEntryTable.setHTML(0, ++idx, "<b>Total Records</b>");
                    formatter.addStyleName(0, idx, "tdleft");
                    formatter.setWordWrap(0, idx, false);

                    searchResultsEntryTable.getRowFormatter().setStyleName(0, "nfseth");

                }

                int numRows = summaries.length + 1;
                while (searchResultsEntryTable.getRowCount() > numRows)
                    searchResultsEntryTable.removeRow(numRows);

                for (int i = 0; i < summaries.length; i++) {

                    if (i % 2 == 0)
                        searchResultsEntryTable.getRowFormatter().setStyleName(i + 1, "nfsetr");
                    else
                        searchResultsEntryTable.getRowFormatter().setStyleName(i + 1, "nfsetrodd");

                    final QuerySummary qs = summaries[i];

                    int idx = -1;

                    final CheckBox check = new CheckBox();
                    check.setChecked(false);
                    if (checkedMyQueriesIDs.get(summaries[i].queryID) != null) {
                        check.setChecked(true);
                    }
                    check.setName(summaries[i].queryID);
                    check.addClickListener(new ClickListener() {
                        public void onClick(Widget sender) {
                            if (check.isChecked()) {
                                checkedMyQueriesIDs.put(qs.queryID, "");
                            } else {
                                checkedMyQueriesIDs.remove(qs.queryID);
                            }
                        }
                    });

                    Hyperlink openLink = new Hyperlink(summaries[i].queryID, summaries[i].queryID);
                    openLink.addClickListener(new ClickListener() {
                        public void onClick(Widget sender) {
                            client.openQuery(qs.queryID);
                        }
                    });

                    searchResultsEntryTable.setWidget(i + 1, ++idx, check);
                    searchResultsEntryTable.setWidget(i + 1, ++idx, openLink);
                    formatter.addStyleName(i + 1, idx, "nfsetd");

                    String ts = summaries[i].ts;
                    if (ts.equals("0000-00-00 00:00:00.0"))
                        ts = "Permanent";

                    // FlexTable actionTable = new FlexTable();
                    // FlexTable.FlexCellFormatter actionFormatter =
                    // actionTable.getFlexCellFormatter();
                    // int idx2 = -1;

                    // actionTable.setWidget(0, ++idx2, openLink);
                    // actionFormatter.setWordWrap(0, idx2, false);

                    // actionTable.setHTML(0, ++idx2, "|");

                    // actionTable.setWidget(0, ++idx2, deleteLink);
                    // actionFormatter.setWordWrap(0, idx2, false);

                    // actionTable.setHTML(0, ++idx2, "|");

                    // actionTable.setWidget(0, ++idx2,
                    // myQueriesCheckBoxes[i]);
                    // actionFormatter.setWordWrap(0, idx2, false);

                    /*
                     * if (!ts.equals("Permanent")) { actionTable.setHTML(0,
                     * ++idx2, "|"); Hyperlink makePermLink = new Hyperlink();
                     * makePermLink.setHTML("Make Permanent");
                     * makePermLink.addClickListener(new ClickListener() {
                     * public void onClick(Widget sender) {
                     * makePermanent(queryID); } }); actionTable.setWidget(0,
                     * ++idx2, makePermLink); actionFormatter.setWordWrap(0,
                     * idx2, false); }
                     */

                    // myQueriesEntryTable.setWidget(i + 1, ++idx,
                    // actionTable);
                    // myQueriesEntryTable.setHTML(i + 1, ++idx, ts);
                    // formatter.setWordWrap(i + 1, idx - 1, false);
                    String note = summaries[i].note;
                    final String tempNote = note;
                    if (note.length() == 0)
                        note = "None";

                    String displayNote = note;
                    if (displayNote.length() > 30) {
                        displayNote = displayNote.substring(0, 14) + "...";
                    }

                    Hyperlink editNoteLink = new Hyperlink(displayNote, "");
                    editNoteLink.addClickListener(new ClickListener() {
                        public void onClick(Widget sender) {
                            
                            NoteDialogBox noteDialog = new NoteDialogBox(client);
                            noteDialog.setNote(tempNote);
                            noteDialog.setQueryID(qs.queryID);
                            noteDialog.setTitle("Note for " + qs.queryID);
                            noteDialog.show();
                        }
                    });

                    // noteTable.setWidget(0, 2, editNoteLink);

                    searchResultsEntryTable.setWidget(i + 1, ++idx, editNoteLink);
                    formatter.addStyleName(i + 1, idx, "nfsetd");

                    searchResultsEntryTable.setHTML(i + 1, ++idx, summaries[i].ts);
                    formatter.addStyleName(i + 1, idx, "nfsetd");

                    String status = "In progress";
                    if (summaries[i].status == 1)
                        status = "Complete";
                    else if (summaries[i].status == 2)
                        status = "Merging";
                    searchResultsEntryTable.setHTML(i + 1, ++idx, "" + status);
                    formatter.addStyleName(i + 1, idx, "nfsetd");

                    int[] types = client.getAllTypes();
                    for (int x = 0; x < types.length; x++) {
                        String typeCountStr = " ";
                        int typeCount = summaries[i].getTypeCount(types[x]);
                        if (typeCount != -1)
                            typeCountStr = "" + typeCount;

                        searchResultsEntryTable.setHTML(i + 1, ++idx, typeCountStr);
                        formatter.addStyleName(i + 1, idx, "nfsetd");
                        formatter.addStyleName(i + 1, idx, "tdright");

                    }

                    String countStr = summaries[i].count + "";
                    if (summaries[i].status != 1)
                        countStr = "-";
                    searchResultsEntryTable.setHTML(i + 1, ++idx, countStr);
                    formatter.addStyleName(i + 1, idx, "nfsetd");
                    formatter.addStyleName(i + 1, idx, "tdright");

                }

            }
        };

        nfseService.myQueries(callback);
    }

}
